home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / oath.lha / oath / src / pdlQueue.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-29  |  9.8 KB  |  438 lines

  1. //***************************************************************************
  2. //             OATH :: Object-oriented Abstract Type Hierarchy
  3. //***************************************************************************
  4. //
  5. //  Copyright (C) 1991, 1990  Texas Instruments Incorporated
  6. //  Permission is granted to any individual or institution
  7. //  to use, copy, modify, and distribute this software,
  8. //  provided that this complete copyright and permission notice
  9. //  is maintained, intact, in all copies and supporting documentation.
  10. //
  11. //  Texas Instruments Incorporated provides this software "as is"
  12. //  without express or implied warranty.
  13. //
  14. //***************************************************************************
  15. //  pdlQueue (pdlQueueA, pdlQueueG)
  16. //  pdlPos (pdlPosA, pdlPosG)
  17. //
  18. //  History:
  19. //    07/91  Brian M Kennedy  import, export, typeRegister
  20. //    06/91  Brian M Kennedy  New macros & format; remove printDiagnostic
  21. //    10/90  Brian M Kennedy  Major Rewrite
  22. //    02/90  Brian M Kennedy  Original
  23. //
  24. //***************************************************************************
  25.  
  26. #include "copyright.h"
  27.  
  28. #include <oath/pdlQueue.h>
  29.  
  30. #include <iostream.h>
  31.  
  32. /////////////////////////////////////////////////////////////////////////////
  33. // pdlQueue Outlines
  34.  
  35. OUTLINES(pdlQueue, lifoQueue)
  36.  
  37. // Constructors //////////
  38.  
  39.     pdlQueueG::
  40. pdlQueueG (int IsConst) // IsConst = FALSE)
  41.    :lifoQueueG(IsConst), Header(0), PosList(0)
  42.    {ref();
  43.        {Header = new slNodeP;}
  44.     deref();
  45.    }
  46.  
  47.     pdlQueueG::
  48. pdlQueueG (const seqG* S, int IsConst) // IsConst = FALSE)
  49.    :lifoQueueG(IsConst), Header(0), PosList(0)
  50.    {ref();
  51.        {slNodeP* End = Header = new slNodeP;
  52.         for(posA P = S->makePos(0, 0); P(); ++P)
  53.         End = End->insertAfter((*P).guts());
  54.        }
  55.     deref();
  56.    }
  57.  
  58.     pdlQueueG::
  59. pdlQueueG (const posG* Start, const posG* Beyond, int IsConst) // IsConst=FALSE
  60.    :lifoQueueG(IsConst), Header(0), PosList(0)
  61.    {ref();
  62.        {slNodeP* End = Header = new slNodeP;
  63.     if(!Beyond)
  64.         for(posA P = (posA&)Start->makeCopy(0); P(); ++P)
  65.             End = End->insertAfter((*P).guts());
  66.     else
  67.        {ensure(Start->parent() == Beyond->parent(), 
  68.            "The two pos's are not from the same seq!");
  69.         slNodeP* End = Header;
  70.             for(posA P = (posA&)Start->makeCopy(0); 
  71.                          (Beyond != P.guts()) && P(); ++P)
  72.             End = End->insertAfter((*P).guts());
  73.         ensure(Beyond == P.guts(),"The second pos is not after the first!");
  74.        }
  75.        }
  76.     deref();
  77.    }
  78.  
  79.     pdlQueueG::
  80. ~pdlQueueG ()
  81.    {assumed(!PosList, "pdlQueue deleted when it still has Pos's!");
  82.     ref();
  83.        {while(Header->next())
  84.         Header->deleteNext();
  85.     delete Header;
  86.        }
  87.     deref();
  88.    }
  89.  
  90.  
  91. // oathCore Operations //////////
  92.  
  93.     void pdlQueueG::
  94. export (exportP& X) const
  95.    {X.writeType(TypeName);
  96.     int Count = count();
  97.     X.stream() << Count << (isConst() ? ' ' : '\0');
  98.     if(Count)
  99.        {for(posA P = makePos(0, 0); P(); ++P)
  100.             (*P).export(X);
  101.        }
  102.    }
  103.  
  104.     objA pdlQueueG::
  105. import (importP& M)
  106.    {int Count;
  107.     M.stream() >> Count;
  108.     char MakeConst = M.stream().get();
  109.     if(Count)
  110.        {slNodeP * Header = new slNodeP;
  111.         slNodeP * End = Header;
  112.     for(int I = 0; I < Count; ++I)
  113.            {objA Tmp = objA::import(M);
  114.         End->Next = new slNodeP (0, Tmp.guts());
  115.         End = End->Next;
  116.            }
  117.     return new pdlQueueG (Header, MakeConst);
  118.        }
  119.     else
  120.         return new pdlQueueG (MakeConst);
  121.    }
  122.  
  123.     void pdlQueueG::
  124. clearReferences()
  125.    {clearMark();
  126.     for(slNodeP *N = Header->next(); N; N = N->next())
  127.     N->thisObj().guts()->deref();
  128.    }
  129.  
  130.     void pdlQueueG::
  131. setReferences()
  132.    {if(!isMarked())
  133.        {setMark();
  134.         for(slNodeP *N = Header->next(); N; N = N->next())
  135.            {N->thisObj().guts()->ref();
  136.         N->thisObj().guts()->setReferences();
  137.        }
  138.        }
  139.    }
  140.  
  141.  
  142. // obj Operations //////////
  143.  
  144.     int pdlQueueG::
  145. isEqual (const objG* O) const
  146.    {if(is(O))
  147.     return TRUE;
  148.     else if(!O->isImplementedAs(Type))
  149.     return FALSE;
  150.     else
  151.        {const pdlQueueG* L = (const pdlQueueG*)O;
  152.     posA Pthis = makePos(0, 0);
  153.     posA PL    = L->makePos(0, 0);
  154.     while(TRUE)
  155.        {if(Pthis.isPastEnd())
  156.         return (PL.isPastEnd() ? TRUE : FALSE);
  157.         if(PL.isPastEnd())
  158.         return FALSE;
  159.         if(!(*Pthis).is(*PL))
  160.         return FALSE;
  161.         ++Pthis;
  162.         ++PL;
  163.        }
  164.        }
  165.    }
  166.  
  167.     objA pdlQueueG::
  168. makeCopy (int MakeConst) const
  169.    {slNodeP * NewHead = new slNodeP;
  170.     slNodeP * NewEnd = NewHead;
  171.     for(slNodeP * P = Header; P->next(); P = P->next())
  172.     NewEnd = NewEnd->insertAfter(P->nextObj().guts());
  173.     return new pdlQueueG (NewHead, MakeConst);
  174.    }
  175.  
  176. // bag Operations //////////
  177.  
  178.     int pdlQueueG::
  179. count () const
  180.    {int C = 0;
  181.     for(slNodeP *N = Header->next(); N; N = N->next())
  182.     C++;
  183.     return C;
  184.    }
  185.  
  186.     int pdlQueueG::
  187. contains (const objG* O) const
  188.    {for(slNodeP *N = Header->next(); N; N = N->next())
  189.     if(O->is(N->thisObj().guts()))
  190.         return TRUE;
  191.     return FALSE;
  192.    }
  193.  
  194.     int pdlQueueG::
  195. containsEqual (const objG* O) const
  196.    {for(slNodeP *N = Header->next(); N; N = N->next())
  197.     if(O->isEqual(N->thisObj().guts()))
  198.         return TRUE;
  199.     return FALSE;
  200.    }
  201.  
  202.     int pdlQueueG::
  203. canContain (const objG*) const
  204.    {return TRUE;}
  205.  
  206.     void pdlQueueG::
  207. insert (const objG* O)
  208.    {NOT_CONST();
  209.     Header->insertAfter(O);
  210.    }
  211.  
  212.     void pdlQueueG::
  213. append (const bagG* B)
  214.    {NOT_CONST();
  215.     B->applyX(callSelf, this);
  216.    }
  217.  
  218.     void pdlQueueG::
  219. apply (void (*F)(objA)) const
  220.    {for(slNodeP *N = Header->next(); N; N = N->next())
  221.     F(N->thisObj());
  222.    }
  223.  
  224.     bagG* pdlQueueG::
  225. applyX (objA (*F)(objA), bagG* B) const
  226.    {for(slNodeP *N = Header->next(); N; N = N->next())
  227.        {objA O = F(N->thisObj());
  228.         B->insert(O.guts());
  229.        }
  230.     return B;
  231.    }
  232.  
  233.     bagG* pdlQueueG::
  234. applyX (bagA (*F)(objA), bagG* B) const
  235.    {for(slNodeP *N = Header->next(); N; N = N->next())
  236.        {bagA O = F(N->thisObj());
  237.         B->append(O.guts());
  238.        }
  239.     return B;
  240.    }
  241.  
  242.     bagA pdlQueueG::
  243. makeEmpty () const
  244.    {return new pdlQueueG ();}
  245.  
  246.  
  247. // queue Operations //////////
  248.  
  249.     const objG* pdlQueueG::
  250. remove ()
  251.    {NOT_CONST();
  252.     assumed(!isEmpty(), "remove() attempted on an empty Queue!");
  253.     adjustPosList(Header->next(), Header);
  254.     const objG* O = Header->nextObj().guts();
  255.     Header->deleteNext();
  256.     return O;
  257.    }
  258.  
  259.  
  260. // seq Operations //////////
  261.  
  262.     seqA pdlQueueG::
  263. makeSeq (const posG* Start, const posG* Beyond, int MakeConst) const
  264.    {return new pdlQueueG (Start, Beyond, MakeConst);}
  265.  
  266.     seqA pdlQueueG::
  267. makeSeq (int Start, int Beyond, int MakeConst) const
  268.    {posA S = makePos(Start, TRUE);
  269.     posA B = makePos(Beyond,TRUE);
  270.     return new pdlQueueG (S.guts(), B.guts(), MakeConst);
  271.    }
  272.  
  273.  
  274. // lifoQueue Operations //////////
  275.  
  276.  
  277. // pdlQueue Operations //////////
  278.  
  279.     slNodeP* pdlQueueG::
  280. internalPosition (int I) const
  281.    {if(!I)
  282.            return Header;
  283.     slNodeP * N = Header;
  284.     for(int J = 0; (J < I) && N->next(); J++)
  285.     N = N->next();
  286.     return N;
  287.    }
  288.  
  289.     void pdlQueueG::
  290. adjustPosList(slNodeP* CurrentPrev, slNodeP* NewPrev)
  291.    {pdlPosG* Pos = PosList;
  292.     while(Pos)
  293.        {if(Pos->Prev == CurrentPrev)
  294.         Pos->Prev = NewPrev;
  295.     Pos = Pos->NextPos;
  296.        }
  297.    }
  298.  
  299.  
  300. /////////////////////////////////////////////////////////////////////////////
  301. // pdlPos Outlines
  302.  
  303. OUTLINES(pdlPos, pos)
  304.  
  305.     pdlPosG::
  306. pdlPosG (const pdlQueueG* iList, slNodeP* iPrev, int IsConst) // IsConst = FALSE
  307.    :posG(IsConst), List(iList), Prev(iPrev), PrevPos(0),
  308.                          NextPos(iList->posList())
  309.    {if(NextPos)
  310.         NextPos->PrevPos = this;
  311.     List.guts()->posList() = this;
  312.    }
  313.  
  314.     pdlPosG::
  315. ~pdlPosG ()
  316.    {if(NextPos)
  317.     NextPos->PrevPos = PrevPos;
  318.     if(PrevPos)
  319.     PrevPos->NextPos = NextPos;
  320.     else
  321.         List.guts()->posList() = NextPos;
  322.    }
  323.  
  324.  
  325. // oathCore Operations //////////
  326.  
  327.     void pdlPosG::
  328. export (exportP& X) const
  329.    {X.writeType(TypeName);
  330.     List.export(X);
  331.     int I = 0;
  332.     pdlPosA P = List.makePos();
  333.     while(P.guts()->Prev != Prev)
  334.        {++P; ++I;}
  335.     X.stream() << I << (isConst() ? ' ' : '\0');    
  336.    }
  337.  
  338.     objA pdlPosG::
  339. import (importP& M)
  340.    {pdlQueueA Q = pdlQueueA::isa(objA::import(M));
  341.     int I;
  342.     M.stream() >> I;
  343.     char MakeConst = M.stream().get();
  344.     return Q.makePos(I, MakeConst);
  345.    }
  346.  
  347.     void pdlPosG::
  348. clearReferences()
  349.    {clearMark();
  350.     List.guts()->deref();
  351.    }
  352.  
  353.     void pdlPosG::
  354. setReferences()
  355.    {if(!isMarked())
  356.        {setMark();
  357.         List.guts()->ref();
  358.     List.guts()->setReferences();
  359.        }
  360.    }
  361.  
  362.  
  363. // obj Operations //////////
  364.  
  365.     int pdlPosG::
  366. isEqual (const objG* O) const
  367.    {return O->isImplementedAs(Type) && (Prev == ((const pdlPosG*)O)->Prev);}
  368.  
  369.  
  370. // pos Operations //////////
  371.  
  372.     const objG* pdlPosG::
  373. indirection () const
  374.    {assumed(Prev->Next, "operator * attempted past end of Sequence");
  375.     return Prev->nextObj().guts();
  376.    }
  377.  
  378.     void pdlPosG::
  379. increment ()
  380.    {NOT_CONST();
  381.     if(Prev->next())
  382.         Prev = Prev->next();
  383.    }
  384.  
  385.     void pdlPosG::
  386. increment (int I)
  387.    {NOT_CONST();
  388.     for(int J = 0; (J < I) && Prev->next(); J++)
  389.     Prev = Prev->next();
  390.    }
  391.  
  392.     const objG* pdlPosG::
  393. find (const objG* O)
  394.    {NOT_CONST();
  395.     slNodeP * P = Prev;
  396.     slNodeP * N;
  397.     while(N = P->next())
  398.        {if(O->is(N->thisObj().guts()))
  399.        {Prev = P;
  400.         return O;
  401.        }
  402.     P = N;
  403.        }
  404.     return objG::Nil;
  405.    }
  406.  
  407.     const objG* pdlPosG::
  408. findEqual (const objG* O)
  409.    {NOT_CONST();
  410.     slNodeP * P = Prev;
  411.     slNodeP * N;
  412.     while(N = P->next())
  413.        {if(O->isEqual(N->thisObj().guts()))
  414.        {Prev = P;
  415.         return O;
  416.        }
  417.     P = N;
  418.        }
  419.     return objG::Nil;
  420.    }
  421.  
  422.     void pdlPosG::
  423. reset (const posG* P)
  424.    {NOT_CONST();
  425.     ensure(P->isImplementedAs(Type) && List.is(((pdlPosG*)P)->List),
  426.        "Pos's not from same seq!");
  427.     Prev = ((const pdlPosG*)P)->Prev;
  428.    }
  429.  
  430.     void pdlPosG::
  431. reset (int Index)
  432.    {NOT_CONST();
  433.     Prev = List.guts()->internalPosition(Index);
  434.    }
  435.  
  436.  
  437. //***************************************************************************
  438.